# Error Handling
Most likely your application is going to contain bugs or otherwise throw an exception that needs to be handled. For example, if the user follows a link to a resource that no longer exists in the database, Active Record will throw the ActiveRecord::RecordNotFound
exception.
Rails default exception handling displays a "500 Server Error" message for all exceptions. If the request was made locally, a nice traceback and some added information gets displayed, so you can figure out what went wrong and deal with it. If the request was remote Rails will just display a simple "500 Server Error" message to the user, or a "404 Not Found" if there was a routing error, or a record could not be found. Sometimes you might want to customize how these errors are caught and how they're displayed to the user. There are several levels of exception handling available in a Rails application:
The Default 500 and 404 Templates
By default, in the production environment the application will render either a 404, or a 500 error message. In the development environment all unhandled exceptions are simply raised. These messages are contained in static HTML files in the public folder, in
404.html
and500.html
respectively. You can customize these files to add some extra information and style, but remember that they are static HTML; i.e. you can't use ERB, SCSS, CoffeeScript, or layouts for them.rescue_from
If you want to do something a bit more elaborate when catching errors, you can use
rescue_from
, which handles exceptions of a certain type (or multiple types) in an entire controller and its subclasses.When an exception occurs which is caught by a
rescue_from
directive, the exception object is passed to the handler. The handler can be a method or aProc
object passed to the:with
option. You can also use a block directly instead of an explicitProc
object.Here's how you can use
rescue_from
to intercept allActiveRecord::RecordNotFound
errors and do something with them.class ApplicationController < ActionController::Base rescue_from ActiveRecord::RecordNotFound, with: :record_not_found private def record_not_found render plain: "404 Not Found", status: 404 end end
1
2
3
4
5
6
7
8Of course, this example is anything but elaborate and doesn't improve on the default exception handling at all, but once you can catch all those exceptions you're free to do whatever you want with them. For example, you could create custom exception classes that will be thrown when a user doesn't have access to a certain section of your application:
class ApplicationController < ActionController::Base rescue_from User::NotAuthorized, with: :user_not_authorized private def user_not_authorized flash[:error] = "You don't have access to this section." redirect_back(fallback_location: root_path) end end class ClientsController < ApplicationController # Check that the user has the right authorization to access clients. before_action :check_authorization # Note how the actions don't have to worry about all the auth stuff. def edit @client = Client.find(params[:id]) end private # If the user is not authorized, just throw the exception. def check_authorization raise User::NotAuthorized unless current_user.admin? end end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25